<!doctype html>
<html lang="en-US">
  <head>
    <title>Web Chat: Decorate bot activity with upvote and downvote buttons</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!--
      For simplicity and code clarity, we are using Babel and React from unpkg.com.
    -->
    <script crossorigin="anonymous" src="https://unpkg.com/@babel/standalone@7.8.7/babel.min.js"></script>
    <script crossorigin="anonymous" src="https://unpkg.com/react@16.8.6/umd/react.development.js"></script>
    <script crossorigin="anonymous" src="https://unpkg.com/react-dom@16.8.6/umd/react-dom.development.js"></script>
    <script crossorigin="anonymous" src="https://unpkg.com/react-redux@7.1.0/dist/react-redux.min.js"></script>
    <!--
      This CDN points to the latest official release of Web Chat. If you need to test against Web Chat's latest bits, please refer to using Web Chat's latest bits:
      https://github.com/microsoft/BotFramework-WebChat#how-to-test-with-web-chats-latest-bits
    -->
    <script crossorigin="anonymous" src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>
    <style>
      html,
      body {
        height: 100%;
      }

      body {
        margin: 0;
      }

      #webchat {
        height: 100%;
        width: 100%;
      }

      .botActivityDecorator {
        min-height: 60px;
        position: relative;
      }

      .botActivityDecorator .botActivityDecorator__content {
        padding-left: 40px;
      }

      .botActivityDecorator .botActivityDecorator__buttonBar {
        list-style-type: none;
        margin: 0 0 0 10px;
        padding: 0;
        position: absolute;
      }

      .botActivityDecorator .botActivityDecorator__buttonBar .botActivityDecorator__button {
        background: White;
        border: solid 1px #e6e6e6;
        margin-bottom: 2px;
        padding: 2px 5px 5px;
      }
    </style>
  </head>

  <body>
    <div id="webchat" role="main"></div>
    <script type="text/babel" data-presets="es2015,react,stage-3">
      (async function () {
        'use strict';

        // In this demo, we are using Direct Line token from MockBot.
        // Your client code must provide either a secret or a token to talk to your bot.
        // Tokens are more secure. To learn about the differences between secrets and tokens
        // and to understand the risks associated with using secrets, visit https://docs.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-direct-line-3-0-authentication?view=azure-bot-service-4.0

        const {
          hooks: { usePostActivity },
          ReactWebChat
        } = window.WebChat;

        const { useCallback } = window.React;

        const BotActivityDecorator = ({ activityID, children }) => {
          const postActivity = usePostActivity();

          const addMessageReaction = helpful => {
            postActivity({
              type: 'messageReaction',
              reactionsAdded: [{ type: helpful === 1 ? 'ThumbsUp' : 'ThumbsDown' }],
              replyToId: activityID
            });
          };

          const handleDownvoteButton = useCallback(() => {
            addMessageReaction(-1);
          }, [activityID, postActivity]);

          const handleUpvoteButton = useCallback(() => {
            addMessageReaction(1);
          }, [activityID, postActivity]);

          return (
            <div className="botActivityDecorator">
              <ul className="botActivityDecorator__buttonBar">
                <li>
                  <button className="botActivityDecorator__button" onClick={handleUpvoteButton}>
                    👍
                  </button>
                </li>
                <li>
                  <button className="botActivityDecorator__button" onClick={handleDownvoteButton}>
                    👎
                  </button>
                </li>
              </ul>
              <div className="botActivityDecorator__content">{children}</div>
            </div>
          );
        };

        const res = await fetch(
          'https://hawo-mockbot4-token-app.blueriver-ce85e8f0.westus.azurecontainerapps.io/api/token/directline',
          { method: 'POST' }
        );
        const { token } = await res.json();
        const activityMiddleware =
          () =>
          next =>
          (...setupArgs) => {
            const [card] = setupArgs;

            if (card.activity.type === 'messageReaction') {
              // Currently, Web Chat does not handle "messageReaction" activity and will show a warning in console log as it is an unknown activity.
              // In this sample, we will disable the rendering of "messageReaction" activity, so the warning is not shown.
              return false;
            } else if (card.activity.from.role === 'bot') {
              return (...renderArgs) => (
                <BotActivityDecorator key={card.activity.id} activityID={card.activity.id}>
                  {next(...setupArgs)(...renderArgs)}
                </BotActivityDecorator>
              );
            }

            return next(...setupArgs);
          };

        window.ReactDOM.render(
          <ReactWebChat
            activityMiddleware={activityMiddleware}
            directLine={window.WebChat.createDirectLine({ token })}
          />,
          document.getElementById('webchat')
        );

        document.querySelector('#webchat > *').focus();
      })().catch(err => console.error(err));
    </script>
  </body>
</html>
